package com.headfirst.CreateMode.builder.version1;

/**
 * 建造者模式的核心：
 * 先把所有的属性都设置给 Builder，然后 build() 方法的时候，将这些属性复制 给实际产生的对象。
 */
public class User {

    // User类中有 “一堆” 属性
    private String name;
    private String password;
    private String nickName;
    private int age;

    // 私有化构造函数
    private User(String name, String password, String nickName, int age) {
        this.name = name;
        this.password = password;
        this.nickName = nickName;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", nickName='" + nickName + '\'' +
                ", age=" + age +
                '}';
    }

    public static UserBuilder builder(String name, String password) {
        return new UserBuilder(name, password);
    }

    public static class UserBuilder {
        // 和User类一模一样的属性
        private String name;
        private String password;
        private String nickName;
        private int age;

        // 在构造方法中强制让调用者提供必填字段
        private UserBuilder(String name, String password) {
            this.name = name;
            this.password = password;
        }

        // 链式调用设置各个属性值，返回this，即 userBuilder
        public UserBuilder name(String name) {
            this.name = name;
            return this;
        }

        public UserBuilder password(String password) {
            this.password = password;
            return this;
        }

        public UserBuilder nickName(String nickName) {
            this.nickName = nickName;
            return this;
        }

        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }

        // build() 方法负责将 UserBuilder 中设置好的属性“复制”到 User 中。
        // 当然，可以在 “复制” 之前做点检验
        public User build() {
            if (name == null || password == null) {
                throw new RuntimeException("用户名和密码必填");
            }
            if (age <= 0 || age >= 150) {
                throw new RuntimeException("年龄不合法");
            }
            // 还可以做赋予”默认值“的功能
            if (nickName == null) {
                nickName = name;
            }
            return new User(name, password, nickName, age);
        }
    }
}
